package com.seed.core.query;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.query.*;
import com.seed.application.Sa;
import com.seed.core.enumeration.JoinType;
import com.seed.core.enumeration.PropertyType;
import com.seed.core.enumeration.StatType;
import com.seed.core.pojo.Join;
import com.seed.core.pojo.seed.*;
import com.seed.core.query.pojo.Declared;
import com.seed.core.query.pojo.Searched;
import com.seed.util.StrKit;

import java.util.*;

public class SeedStat {
//    private final Seed seed;
//
//    private final Stat stat;
//    private SeedSearched seedSearched;
//    private SeedKeyword seedKeyword;
//    private SeedDataPermied seedDataPermied;
//
//    private final Map<String, Join> joins = new LinkedHashMap<>();
//
//    public SeedStat(Seed seed, Stat stat) {
//        this.seed = seed;
//        this.stat = stat;
//    }
//
//    public SeedStat(Seed seed, Stat stat, Map<String, Searched> searcheds) {
//        this(seed, stat);
//        this.seedSearched = new SeedSearched(seed, searcheds);
//    }
//
//    public QueryWrapper getQueryWrapper() {
//        Micro micro = Sa.getMicro();
//
//        QueryTable table = new QueryTable(seed.getTableName()).as("t");
//        QueryWrapper qw = QueryWrapper.create().from(table);
//
//        StatType statType = stat.getType();
//        String declare = stat.getDeclare();
//        Map<String, Declared> declareds = micro.buildDeclared(seed, declare);
//        Map.Entry<String, Declared> first = declareds.entrySet().iterator().next();
//        Declared declared = first.getValue();
//        switch (declared.getType()) {
//            case none, asterisk -> {
//                if(!statType.equals(StatType.count)) throw new RuntimeException("只有【count】可以用【*】");
//                qw.select("count(*)");
//            }
//            case column -> {
//                Column column = micro.getColumn(seed, declare);
//                qw.select(String.format("%s(`t`.`%s`)", statType, column.getName()));
//            }
//            default -> {
//                qw.select(String.format("`%s`.`id`", inSelectAlias(null, declareds)));
//                initJoins(null, declareds);
//            }
//        }
//
//        Map<String, Join> joinList = new LinkedHashMap<>();
//        for(Map.Entry<String, Join> entry: joins.entrySet()) {
//            joinList.putIfAbsent(entry.getKey(), entry.getValue());
//        }
//        if(seedSearched != null) {
//            for(Map.Entry<String, Join> entry: seedSearched.getJoins().entrySet()) {
//                joinList.putIfAbsent(entry.getKey(), entry.getValue());
//            }
//        }
//        if(seedKeyword != null) {
//            for(Map.Entry<String, Join> entry: seedKeyword.getJoins().entrySet()) {
//                joinList.putIfAbsent(entry.getKey(), entry.getValue());
//            }
//        }
//        if(seedDataPermied != null) {
//            for(Map.Entry<String, Join> entry: seedDataPermied.getJoins().entrySet()) {
//                joinList.putIfAbsent(entry.getKey(), entry.getValue());
//            }
//        }
//
//        for(Join join: joinList.values()) {
//            QueryTable queryTable = join.getTable();
//            QueryCondition on = join.getOn();
//            JoinType type = join.getJoinType();
//            switch (type) {
//                case inner -> qw.innerJoin(queryTable).on(on);
//                case left -> qw.leftJoin(queryTable).on(on);
//                default -> throw new RuntimeException(String.format("暂时不支持【%s】", type));
//            }
//        }
//
//        Map<String, SeedInCondition> inQuerys = new LinkedHashMap<>();
//        if(seedSearched != null) inQuerys.putAll(seedSearched.getInQuerys());
//
//        if(seedKeyword != null) {
//            for(Map.Entry<String, SeedInCondition> entry: seedKeyword.getInQuerys().entrySet()) {
//                String key = entry.getKey();
//                SeedInCondition value = entry.getValue();
//                SeedInCondition seedInCondition = inQuerys.get(key);
//                if(seedInCondition == null) {
//                    inQuerys.putIfAbsent(key, value);
//                } else {
//                    seedInCondition.setDeclared(value.getDeclared());
//                }
//            }
//        }
//
//        for(Map.Entry<String, SeedInCondition> entry: inQuerys.entrySet()) {
//            qw.and(entry.getValue().getQueryCondition());
//        }
//
//        if(seedSearched != null) {
//            for(QueryCondition condition: seedSearched.getWheres()) qw.and(condition);
//        }
//
//        if(seedKeyword != null) {
//            qw.and(queryWrapper -> {
//                for(QueryCondition condition: seedKeyword.getWheres()) queryWrapper.or(condition);
//            });
//        }
//
//        if(seedDataPermied != null) qw.and(seedDataPermied.getQueryCondition());
//
//        return switch (declared.getType()) {
//            case none, asterisk, column -> qw;
//            default -> QueryWrapper.create()
//                .select(String.format("%s(`%s`)", statType, statisColumnName(declareds)))
//                .from(statisTableName(seed, declareds))
//                .where(new RawQueryColumn("id").in(qw));
//        };
//    }
//
//    private void initJoins(String basePath, Map<String, Declared> declareds) {
//        Map.Entry<String, Declared> first = declareds.entrySet().iterator().next();
//        String cross = first.getKey();
//        Declared declared = first.getValue();
//
//        String selfTableAlias = StrKit.selfTableAlias(basePath);
//        String finalPath = StrKit.concat(basePath, cross);
//        Property property = declared.getProperty();
//        if(!(property instanceof Relation relation)) return;
//
//        Seed targetSeed = relation.targetSeed();
//        String targetTableAlias = StrUtil.toCamelCase(finalPath);
//        QueryTable targetTable = new QueryTable(targetSeed.getTableName()).as(targetTableAlias);
//
//        PropertyType propertyType = declared.getType();
//        switch (propertyType) {
//            case hasOne, belongsTo, hasMany -> {
//                QueryCondition on = relation.getQueryCondition(basePath, cross);
//                joins.put(finalPath, new Join(targetTable, on));
//                initJoins(finalPath, declared);
//            }
//            case habtm -> {
////                Habtms habtm = (Habtms) relation;
////                String throughAlias = StrKit.throughAlias(basePath, cross);
////                QueryTable throughTable = new QueryTable(habtm.throughTableName()).as(throughAlias);
////                QueryCondition throughOn = habtm.getThroughQueryCondition(selfTableAlias, throughAlias);
////                joins.put(throughAlias, new Join(throughTable, throughOn, JoinType.inner));
////
////                QueryCondition on = habtm.getQueryCondition(selfTableAlias, throughAlias, targetTableAlias);
////                joins.put(finalPath, new Join(targetTable, on));
////                initJoins(finalPath, declared);
//            }
//        }
//    }
//
//    private String statisTableName(Seed seed, Map<String, Declared> declareds) {
//        Map.Entry<String, Declared> first = declareds.entrySet().iterator().next();
//        Declared declared = first.getValue();
//        return switch (declared.getType()) {
//            case none, asterisk, column -> seed.getTableName();
//            default -> {
//                Relation relation = (Relation) declared.getProperty();
//                yield statisTableName(relation.targetSeed(), declared);
//            }
//        };
//    }
//
//    private String statisColumnName(Map<String, Declared> declareds) {
//        Map.Entry<String, Declared> first = declareds.entrySet().iterator().next();
//        Declared declared = first.getValue();
//        return switch (declared.getType()) {
//            case none, asterisk -> "id";
//            case column -> ((Column) declared.getProperty()).getName();
//            default -> statisColumnName(declared);
//        };
//    }
//
//    private String inSelectAlias(String basePath, Map<String, Declared> declareds) {
//        Map.Entry<String, Declared> first = declareds.entrySet().iterator().next();
//        Declared declared = first.getValue();
//        return switch (declared.getType()) {
//            case none, asterisk, column -> basePath;
//            default -> inSelectAlias(StrKit.concat(basePath, first.getKey()), declared);
//        };
//    }
//
//    public Stat getStat() {
//        return stat;
//    }
//
//    public void setKeyword(String keyword, Map<String, Declared> declareds) {
//        if(StrUtil.isNotBlank(keyword)) this.seedKeyword = new SeedKeyword(keyword, seed, declareds);
//    }
//
//    public void setDataPermieds(List<List<List<Map<String, Searched>>>> dataPermieds) {
//        if(dataPermieds != null) this.seedDataPermied = new SeedDataPermied(seed, dataPermieds);
//    }
}
